package com.yxy.chatserver.handler;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.yxy.chatserver.constant.MessageStatusConstant;
import com.yxy.chatserver.constant.MessageTypeConstant;
import com.yxy.chatserver.domain.po.BaseMessage;
import com.yxy.chatserver.service.MessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.List;

/**
 * websocket处理类
 */
@Component
@Slf4j
public class WebSocketServerHandler extends TextWebSocketHandler {

    @Autowired
    private WebSocketManager webSocketManager;

    @Autowired
    private MessageService messageService;

    @Autowired
    private FriendRequestHandler friendRequestHandler;

    @Autowired
    private MessageWebSocketHandler messageWebSocketHandler;

    @Autowired
    private Gson gson;

    /**
     * 建立连接
     *
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println(3333);
        // 从请求参数中获取用户ID
        String userId = (String) session.getAttributes().get("userId");

        // 如果没有用户ID，则从请求URL中获取
        if (userId == null) {
            String queryString = session.getUri().getQuery();
            if (queryString != null) {
                for (String param : queryString.split("&")) {
                    String[] keyValue = param.split("=");
                    if (keyValue.length == 2 && "userId".equals(keyValue[0])) {
                        userId = keyValue[1];
                        break;
                    }
                }
            }
        }

        // 存储用户会话
        session.getAttributes().put("userId", userId);
        webSocketManager.addUserSession(userId, session);

        log.info("🎯 WebSocket 连接建立");
        log.info("   └─ 用户ID: {}", userId);
        log.info("   └─ 会话ID: {}", session.getId());
        log.info("   └─ 远程地址: {}", session.getRemoteAddress());
        log.info("   └─ 当前连接数: {}", webSocketManager.getConnectionCount());
        log.debug("会话属性: {}", session.getAttributes().toString());

        // 检查用户是否有未读消息，如果有则发送给用户
        List<BaseMessage> unreadBaseMessages = messageService.getUnreadMessages(userId);
        log.info("用户 {} 有 {} 条未读消息", userId, unreadBaseMessages.size());
        if (!unreadBaseMessages.isEmpty()) {
            log.info("发现用户 {} 有 {} 条未读消息，正在发送...", userId, unreadBaseMessages.size());
            for (BaseMessage unreadMsg : unreadBaseMessages) {
                System.out.println(unreadMsg);
                JsonObject message = new JsonObject();
                message.addProperty("type", MessageTypeConstant.OFFLINE_MESSAGE);
                message.add("data", gson.toJsonTree(unreadMsg));
                session.sendMessage(new TextMessage(message.toString()));
                // 更新消息状态为已接收
                messageService.markMessageAsRead(unreadMsg.getId());
            }
        }
    }

    /**
     * 接收消息
     *
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String clientMessage = message.getPayload().toString();

        try {
            // 解析JSON
            JsonObject jsonObject = gson.fromJson(clientMessage, JsonObject.class);
            if (!jsonObject.has("type")) {
                sendErrorMessage(session, "消息格式错误, 缺少 type 字段");
                log.warn("消息格式错误：缺少type字段");
            }
            String messageType = jsonObject.get("type").getAsString();
            String userId = (String) session.getAttributes().get("userId");

            // 根据消息类型分别处理
            switch (messageType) {
                case "heartbeat":
                    // 心跳消息，只记录调试日志，不处理业务逻辑
                    log.debug("💓 心跳检测 - 用户: {}", userId);
                    // 返回心跳响应
//                    sendHeartbeatResponse(session);
                    break;

                case "text":
                case "image":
                case "file":
                    // 业务消息，进行完整处理
                    log.info("📨 业务消息 - 来自用户: {}, 内容: {}", userId, clientMessage);
                    messageWebSocketHandler.handleMessage(session, jsonObject, userId);
                    break;

                case "friendRequest":
                case "acceptRequest":
                case "rejectRequest":
                    log.info("📨 好友请求 - 来自用户: {}, 内容: {}", userId, clientMessage);
                    friendRequestHandler.handleMessage(session, jsonObject, userId);
                    break;

                default:
                    log.warn("❓ 未知消息类型: {}, 来自用户: {}", messageType, userId);
                    break;
            }

        } catch (Exception e) {
            log.error("消息处理失败：{}", e.getMessage());
            sendErrorMessage(session, e.getMessage());
        }
    }

    /**
     * 异常处理
     *
     * @param session
     * @param exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        String userId = "未知用户";
        String sessionId = "未知会话ID";

        if (session != null) {
            userId = (String) session.getAttributes().get("userId");
            if (userId == null) userId = "未知用户";
            sessionId = session.getId();
        }

        // 详细记录异常信息
        log.warn("WebSocket异常：用户[{}]，会话ID[{}]", userId, sessionId);
        log.warn("异常类型：{}", exception.getClass().getName());
        log.warn("异常消息：{}", exception.getMessage());

        // 记录异常堆栈信息
        log.debug("异常堆栈信息", exception);

        // 异常时关闭连接
        if (session != null && session.isOpen()) {
            try {
                session.close(CloseStatus.SERVER_ERROR);
                log.info("已关闭异常会话");
            } catch (Exception e) {
                log.warn("关闭会话失败：{}", e.getMessage());
            }
        }

        // 清理用户会话
        if (userId != null && !userId.equals("未知用户")) {
            webSocketManager.removeUserSession(userId);
            log.info("异常关闭用户 {} 的连接", userId);
        }
    }

    /**
     * 关闭连接
     *
     * @param session
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        // 获取用户ID并清理会话
        String userId = (String) session.getAttributes().get("userId");
        if (userId != null) {
            webSocketManager.removeUserSession(userId);
            log.info("与用户 {} 断开连接，关闭状态：{}", userId, closeStatus);
            log.info("关闭代码: {}, 关闭原因: {}", closeStatus.getCode(), closeStatus.getReason());
            log.info("当前连接数: {}", webSocketManager.getConnectionCount());
        } else {
            log.debug("与未知用户断开连接");
        }
    }

    /**
     * 发送心跳响应
     */
    private void sendHeartbeatResponse(WebSocketSession session) throws Exception {
        JsonObject response = new JsonObject();
        response.addProperty("type", "heartbeat");
        response.addProperty("timestamp", System.currentTimeMillis());
        response.addProperty("content", "PONG");
        session.sendMessage(new TextMessage(response.toString()));
    }

    /**
     * 发送错误消息
     */
    private void sendErrorMessage(WebSocketSession session, String errorMsg) throws Exception {
        JsonObject error = new JsonObject();
        error.addProperty("type", "error");
        error.addProperty("content", errorMsg);
        session.sendMessage(new TextMessage(error.toString()));
    }
}
